Examples
Only a few examples are shown here. Every method has an example (and plotting code) in the test folder!
Nonlinear
using SignalDecomposition, DynamicalSystems, Random, Plots, Statistics
he = Systems.henon()
tr = trajectory(he, 10000; Ttr = 100)
Random.seed!(151521)
z = tr[:, 1]
s = z .+ randn(10001)*0.1*std(z)
m = 5
w = 1 # theiler window
metric = Euclidean()
k = 30
Q = [2, 2, 2, 3, 3, 3, 3]
x, r = decompose(s, ManifoldProjection(m, Q, k))([0.6406703765906637, 0.5575427502901171, 0.7462518425770176, 0.36025839052516806, 1.036571945094405, -0.4765485431232428, 0.9799134256156551, -0.5118959358781641, 0.9329731351053154, -0.3592701003040989 … -0.7709156882642354, 0.6403391824592206, 0.13992849059669613, 1.1036312914772706, -0.758651253561322, 0.19943488733242642, 0.5937304148309485, 0.6544576703058106, 0.7156849196591015, 0.37807295451585804], [1.2654606551532055e-7, -0.06774468042552456, -0.014037653730505917, -0.03544910033386156, -0.09990644445492736, 0.04813866165816871, 0.06437873455867271, -0.05027097060282826, 0.00908123554750051, -0.07545522168005031 … 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])p1 = plot(s, label = "input")
plot!(p1, z, color = :black, ls = :dash, label = "real")
plot!(p1, x, alpha = 0.5, label = "output")
xlims!(p1, 0, 50)
p1
Alright, this doesn't seem much of a difference to be honest. One sees a big difference once going into the state space and looking at the attractor:
p2 = scatter(s[1:end-1], s[2:end], ms = 1, label = "input", msw = 0)
scatter!(p2, z[1:end-1], z[2:end], ms = 1, label = "real", color = :black, msw = 0)
scatter!(p2, x[1:end-1], x[2:end], ms = 1, label = "output", alpha = 0.5, msw = 0)
p2
Time and Sinusoidal
using SignalDecomposition, Dates, Random, Plots
Random.seed!(41516)
y = Date(2001):Day(1):Date(2025)
dy = dayofyear.(y)
cy = @. 4 + 7.2cos(2π*dy/365.26) + 5.6cos(4π*dy/365.26 + 3π/5)
r0 = randn(length(dy))/2
sy = cy .+ r0
x, r = decompose(y, sy, TimeAnomaly())
t = collect(1:length(y)) ./ 365.26 # true time in years
x2, r2 = decompose(t, sy, Sinusoidal([1.0, 2.0]))
p3 = plot(t, sy, label = "input")
plot!(p3, t, cy, label = "true periodic", color = :black, ls = :dash)
plot!(p3, t, x, label = "TimeAnomaly", alpha = 1.0, color = :red)
plot!(p3, t, x2, label = "Sinusoidal", alpha = 0.5, color = :green)
xlabel!(p3, "years")
xlims!(p3, 0, 1) # zoom in
Allthough not immediatelly obvious from the figure, Sinusoidal performs better:
rmse(cy, x), rmse(cy, x2)(0.12256155875026417, 0.05132616571208623)